"""
医生相关的 Pydantic 模型
"""

""" 
用于接收请求数据的模型（Input Models）
DoctorCreate - 创建医生时的输入数据
DoctorUpdate - 更新医生信息时的输入数据
DoctorForgotPassword - 忘记密码时的输入数据
DoctorLogin - 医生登录时的输入数据
用于响应返回数据的模型（Response Models）
DoctorResponse - 医生信息响应数据
DoctorLoginResponse - 医生登录响应数据
TokenResponse - Token令牌响应数据
说明
输入模型通常用于API接口接收客户端发送的数据，包含数据验证规则
响应模型通常用于API接口向客户端返回数据，定义了返回数据的结构和格式
DoctorBase 是基础模型，被其他模型继承使用，不直接用于接口交互
"""
from pydantic import BaseModel, Field, validator
from typing import Optional
from datetime import datetime


# ========== 基础模型 ==========
class DoctorBase(BaseModel):
    """医生基础字段"""
    name: str = Field(..., min_length=1, max_length=100, description="医生姓名")
    phone: str = Field(..., pattern=r'^1[3-9]\d{9}$', description="手机号")
    gender: Optional[str] = Field(None, description="性别")
    title: Optional[str] = Field(None, max_length=100, description="职称")
    
    @validator('gender')
    def validate_gender(cls, v):
        if v and v not in ['男', '女', '男性', '女性']:
            raise ValueError('性别只能是男、女、男性或女性')
        return v


# ========== 创建医生 ==========
class DoctorCreate(DoctorBase):
    """创建医生时的输入"""
    # 密码长度限制为6-50位
    password: str = Field(..., min_length=6, max_length=50, description="密码")
    
    class Config:
        json_schema_extra = {
            "example": {
                "name": "张医生",
                "phone": "13800138000",
                "password": "123456",
                "gender": "男",
                "title": "主任医师"
            }
        }


# ========== 更新医生 ==========
class DoctorUpdate(BaseModel):
    """更新医生信息（所有字段可选）"""
    name: Optional[str] = Field(None, min_length=1, max_length=100)
    phone: Optional[str] = Field(None, pattern=r'^1[3-9]\d{9}$')
    gender: Optional[str] = None
    title: Optional[str] = Field(None, max_length=100)
    password: Optional[str] = Field(None, min_length=6, max_length=50)
    old_password: Optional[str] = Field(None, description="旧密码（修改密码时需要）")
    new_password: Optional[str] = Field(None, description="新密码（修改密码时需要）")
    
    @validator('gender')
    def validate_gender(cls, v):
        if v and v not in ['男', '女', '男性', '女性']:
            raise ValueError('性别只能是男、女、男性或女性')
        return v


# ========== 忘记密码 ==========
class DoctorForgotPassword(BaseModel):
    """忘记密码"""
    phone: str = Field(..., description="手机号")
    name: str = Field(..., description="医生姓名")


# ========== 医生响应 ==========
class DoctorResponse(DoctorBase):
    """API返回的医生数据（不包含密码）"""
    id: int
    status: int
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True
        json_schema_extra = {
            "example": {
                "id": 1,
                "name": "张医生",
                "phone": "13800138000",
                "gender": "男",
                "title": "主任医师",
                "status": 1,
                "created_at": "2024-11-03T10:00:00",
                "updated_at": "2024-11-03T10:00:00"
            }
        }
    
    def to_flask_format(self) -> dict:
        """转换为原 Flask 项目的响应格式"""
        return {
            "_id": str(self.id),
            "name": self.name,
            "phone": self.phone,
            "gender": self.gender,
            "title": self.title,
            "status": self.status,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }


# ========== 医生登录响应（适配原 Flask 格式）==========
class DoctorLoginResponse(BaseModel):
    """
    医生登录响应 - 适配原 Flask 项目格式
    原项目返回: access_token, id, name, phone, title, gender
    """
    id: int
    name: str
    phone: str
    gender: Optional[str]
    title: Optional[str]
    access_token: str
    
    class Config:
        from_attributes = True
    
    @classmethod
    def from_doctor(cls, doctor, access_token: str) -> dict:
        """
        从 Doctor 对象和 token 创建响应
        返回格式与原 Flask 项目一致
        """
        return {
            "access_token": access_token,
            "id": str(doctor.id),  # 转换为字符串，与原项目一致
            "name": doctor.name,
            "phone": doctor.phone,
            "title": doctor.title,
            "gender": doctor.gender
        }


# ========== 医生登录 ==========
class DoctorLogin(BaseModel):
    """医生登录"""
    phone: str = Field(..., description="手机号")
    password: str = Field(..., description="密码")
    
    class Config:
        json_schema_extra = {
            "example": {
                "phone": "17608430056",
                "password": "admin"
            }
        }


# ========== Token 响应 ==========
class TokenResponse(BaseModel):
    """Token响应"""
    access_token: str = Field(..., description="访问令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    doctor: DoctorResponse = Field(..., description="医生信息")
    
    class Config:
        json_schema_extra = {
            "example": {
                "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                "token_type": "bearer",
                "doctor": {
                    "id": 1,
                    "name": "张医生",
                    "phone": "13800138000",
                    "gender": "男",
                    "title": "主任医师",
                    "status": 1
                }
            }
        }

